package collection.mymap;

import com.google.common.collect.Maps;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import objectpack.Student;
import org.springframework.util.StringUtils;
import org.testng.Assert;
import org.testng.annotations.Test;

public class MapBase1 {
    public static void main(String[] args) {
        Map<Integer, Integer> map = null;
        Map<Integer, Integer> map2 = new HashMap<>();

        System.out.println(map2.size());
        System.out.println(map2);
        System.out.println(map);
//        System.out.println(map.size());
    }

    /**
     * 验证hashMap是无序的
     */
    @Test
    public void mapOrder() {
        Map<Integer, Integer> map = new HashMap<>(4);
        map.put(1, 1);
        map.put(-1, 1);
        map.put(0, 1);
        map.put(-100, 1);

        System.out.println(map);
    }

    @Test
    public void t3() {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("a", 1);
        map1.put("b", 2);

        Map<String, Integer> map2 = new HashMap<>();
        map2.putAll(map1);

        map2.remove("b");
        System.out.println(map1);
        System.out.println(map2);
    }

    /**
     * 复现异常
     */
    @Test
    public void t4() {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("a", 1);
        map1.put("b", 2);
        for (Map.Entry<String, Integer> entry : map1.entrySet()) {
            map1.remove("b");
        }
    }

    /**
     * map键重复时累加的写法
     */
    @Test
    public void t5() {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("1", 1);
        map1.put("2", 1);

        Map<String, Integer> map2 = new HashMap<>();
        map2.put("1", 1);
        map2.put("2", 1);

        map2.forEach((k, v) -> {
            map1.merge(k, v, Integer::sum);
        });

        // out {1=2, 2=2}
        System.out.println(map1);

    }

    @Test
    public void t6() {
        Map<String, Integer> map = new HashMap<>();
        map.put("1", 1);
        map.put("2", 1);

        try {
            for (var ignored : map.entrySet()) {
                map.remove("1");
            }
        }catch (ConcurrentModificationException e) {
            System.out.println("捕获到了异常" + e);
        }
    }

    /**
     * 空map的size值是0
     */
    @Test
    public void t7() {
        var map = new HashMap<Integer, Integer>();
        Assert.assertEquals(map.size(), 0);
    }

    @Test
    public void t8() {
        var map1 = new HashMap<Integer, String>();
        var map2 = new HashMap<Integer, String>();

        // Mapping string values to int keys for map1
        map1.put(10, "Geeks");
        map1.put(15, "4");
        map1.put(20, "Geeks");
        map1.put(25, "Welcomes");
        map1.put(30, "You");

        // Mapping string values to int keys for map2
        map2.put(10, "Geeks");
        map2.put(15, "4");
        // 该值不同
        map2.put(20, "Geek");
        map2.put(25, "Welcomes");
        map2.put(30, "You");

        System.out.println("First Map: " + map1);

        System.out.println("Second Map: " + map2);

        System.out.println("Equality: " + map1.equals(map2));
    }

    /**
     * 如果map存储的是基本类型，那么equals比较的就是键和值是否相同
     */
    @Test
    public void t9() {
        var map1 = new HashMap<Integer, String>();
        var map2 = new HashMap<Integer, String>();

        // Mapping string values to int keys
        map1.put(10, "Geeks");
        map1.put(15, "4");
        map1.put(20, "Geeks");
        map1.put(25, "Welcomes");
        map1.put(30, "You");

        // Mapping string values to int keys
        map2.put(10, "Geeks");
        map2.put(15, "4");
        map2.put(20, "Geeks");
        map2.put(25, "Welcomes");
        map2.put(30, "You");

        System.out.println("First Map: " + map1);

        System.out.println("Second Map: " + map2);
        // true
        System.out.println("Equality: " + map1.equals(map2));
    }

    @Test
    public void t10() {
        Student s1 = new Student("a", 1, "f");
        Student s2 = new Student("a", 1, "f");
        var map1 = new HashMap<Integer, Student>();

        var map2 = new HashMap<Integer, Student>();
        map1.put(1, s1);
        map2.put(1, s2);

        var s = map1.values().stream()
                .map(Student::getSex)
                .count();

        Assert.assertEquals(map2, map1);
    }

    /**
     * map的values()返回的不一定是set
     */
    @Test
    public void t11() {
        var map = new HashMap<Integer, Integer>();
        map.put(1, 0);
        System.out.println(map.values());
//        Assert.assertTrue(map.values() instanceof Set);

    }

    /**
     * 以没有存储元素的map的values方法生成的set，size是0
     */
    @Test
    public void t12() {
        var map = new HashMap<Integer, Integer>();
        var set = new HashSet<>(map.values());
        Assert.assertEquals(set.size(), 0);
    }

    /**
     * 有null值的map生成的set，set会保留null值
     */
    @Test
    public void t13() {
        var map = new HashMap<Integer, Integer>();
        map.put(1, 2);
        map.put(2, null);

        var set = new HashSet<>(map.values());
        // [null, 2]
        System.out.println(set);
    }

    @Test
    private void t99() {
        var map = new HashMap<String, String>();
        map.put("1", "1");


        map.keySet().forEach(k -> {
//            map.remove("2", "1");
            map.remove("2");
            map.remove("1");
            System.out.println(k);
        });
    }

    /**
     * 嵌套的map，
     */
    @Test
    public void t14() {

        var map = new HashMap<String,
            Map<String,
                Map<String, Integer>>>();
        var map2 = new HashMap<String, Map<String, Integer>>();
        var map3 = new HashMap<String, Integer>();
        map3.put("c", 1);
        map2.put("b", map3);

        map.put("a", map2);

        System.out.println(map);

        var tmap = map.get("a").get("b");

        var res = tmap.get("c");
        Assert.assertEquals(res.intValue(), 1);

        map3.put("c", 2);

        res = tmap.get("c");
        Assert.assertEquals(res.intValue(), 2);

    }

    /**
     * putAll参数为null时，会发生NPE
     */
    @Test
    private void t15() {
        var map = new HashMap<Integer, Integer>();

        map.putAll(null);
    }

    /**
     * 以没有元素的map的values作为for循环的数据源，for循环不会执行
     */
    @Test
    private void t16() {
        var map = new HashMap<Integer, Integer>();

        for (Integer i : map.values()) {
            System.out.println(i);
        }

    }

    @Test
    private void t17() {
        var map = new HashMap<String, String>();

        boolean b = map.values().stream().allMatch(StringUtils::isEmpty);

        System.out.println(b);
    }

    @Test
    private void t18() {

        var map = new TreeMap<String, String>();

        map.put("2", "3");
        map.put("3", "2");
        map.put("1", "3");

        map.put("3", "000");

        System.out.println(map);


    }

    @Test
    private void t19() {
        String s = "";
        System.out.println(s.length());
    }

    @Test
    private void t20( ) {
        var map = new TreeMap<String, String>();

        var campMap = new HashMap<String, String>();
        var changeTeam = new HashMap<String, String>();

        campMap.put("1", "");
        changeTeam.put("3", "");


        int slotNum = 5;

        // 多队竞技场，三队
//        if (campType == SlotCampTypeEnum.MULTI_ARENA) {
//            slotNum = 5 * 3;
//            // 漠北远征，两队
//        } else if (campType == SlotCampTypeEnum.HANG_UP_INST) {
//            slotNum = 5 * 2;
//        }

        for (int i = 1; i <= slotNum; i++) {
            map.put(String.valueOf(i), "");
        }

        campMap.forEach(map::put);

        changeTeam.forEach(map::put);

        System.out.println(map);

        // 记录空槽位的数量
        int j = 0;

        for (Map.Entry<String, String> entry : map.entrySet()) {

//            if (StringUtils.isBlank(entry.getValue())) {
//                j++;
//            }

            if (j == 5) {
                System.out.println("error------");
            }

            // 遍历完一组后重置
            if (Integer.parseInt(entry.getKey()) % 5 == 0) {
                j = 0;
            }
        }
    }

    @Test
    public void t21() {

        var map = new HashMap<Integer, Integer>();

        map.put(1, 0);
        map.put(2, 0);
        map.put(3, 0);
        map.put(4, 0);
        map.put(5, 0);
        map.put(6, 0);

        System.out.println(map);

        Iterator<Entry<Integer, Integer>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Integer, Integer> entry = it.next();

            if (entry.getKey() > 3) {
                entry.setValue(1);
            }
        }

        System.out.println(map);

    }

    @Test
    private void t22() {
        var map = new HashMap<Integer, String>();
        for(Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println("111");
        }

    }

    @Test
    private void  t23() {
        var map = new HashMap<String, String>();
        map.put("1", "2");
        map.put("2", "1");
        map.put("3", "2");
        map.put("4", "1");



        Map<String, String> map2 = Maps.filterValues(map, s -> s.equals("1"));
        System.out.println(map2);
    }

    @Test
    private void t24() {
        Long l1 = 1653059515L;
        long l2 = 1653059515;

        System.out.println(l1 == l2);
    }


    @Test
    private void t25() {
        var map = new HashMap<Integer, Integer>();
        map.put(1, 0);
        map.put(2, 0);
        map.put(3, 0);
        map.put(4, 0);
        map.put(5, 0);
        map.put(6, 0);

        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (entry.getKey() > 3) {
                entry.setValue(1);
            }
        }

        System.out.println(map);

    }

    @Test
    private void t26() {

        var map1 = new HashMap<Integer, String>();
        map1.put(1, "a");

        var map2 = new HashMap<String, String>();
        map2.put("a", "100");

        System.out.println(Maps.transformValues(map1, v -> {
            return map2.get(v);
        }));

    }

    private int testNullParam(int a) {
        return a + 1;
    }

    @Test
    private void t27() {
//        var 😄 = new Object();

//        var s2 = 😄 + 😉;
//
//        Assert.assertEquals(s2, 🤪);
    }

    @Test
    private void t28() {
        var map = new HashMap<String, Integer>();
        Integer put = map.put("2", 2);

        System.out.println(map + " put, " + put);

        var compute = map.compute("3", (k, v) -> {
            v = 3;
            return v;
        });

        System.out.println("compute " + compute);

//        return map.put("1", 1);

    }

    @Test(invocationCount = 5)
    private void t29() {

        List.of(11, 3, 88, 9, 0).stream()
            .findAny()
            .ifPresent(System.out::println);

    }



}
